{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Quantum Chemistry with Paddle Quantum's qchem\n",
    "*Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.*\n",
    "\n",
    "qchem, which builds on top of Paddle Quantum, is designed to be a toolkit for quantum chemistry research in quantum computing era. It provides high level APIs for researchers who are interested in leveraging their current quantum chemsitry calculation with quantum computing power. And it also allows experts to write customized code. qchem is currently under active development, feel free to join us by opening issues or pull requests."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Calculating ground state energy of a molecule\n",
    "qchem provides various tools for you to do quantum chemistry calculation. Currently, qchem module supports the following molecular wave function ansatz:\n",
    "* Hardware Efficient ansatz[<sup>1</sup>](#refer-1),\n",
    "* Hartree Fock ansatz[<sup>2</sup>](#refer-2),\n",
    "* Unitary Coupled Cluster singles and doubles (UCCSD) ansatz[<sup>3</sup>](#refer-3).\n",
    "\n",
    "Let's start from example and try to calculate the ground state energy of hydrogen molecule. First, we need to import qchem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import paddle_quantum as pq\n",
    "from paddle_quantum import qchem as pq_qchem\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "import logging\n",
    "logging.basicConfig(level=logging.INFO)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then, we will build a `Molecule` class for a molecule based on properites such as geometry, charge, chemical basis set."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# `driver` is used to calculate various molecular integrals.\n",
    "driver = pq_qchem.PySCFDriver()\n",
    "\n",
    "# Build a Molecule class based on its properties, note, the length unit is Angstrom.\n",
    "mol = pq_qchem.Molecule(\n",
    "    geometry=[(\"H\", [0.0, 0.0, 0.0]), (\"H\", [0.0, 0.0, 0.74])],\n",
    "    basis=\"sto-3g\",\n",
    "    multiplicity=1,   \n",
    "    driver=driver\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we need to choose an wavefunction ansatz for our hydrogen molecule. Let's choose `HardwareEfficient` as the ansatz. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:root:\n",
      "#######################################\n",
      "Molecule\n",
      "#######################################\n",
      "INFO:root:H2\n",
      "INFO:root:Geometry:\n",
      "INFO:root:H 0.00000, 0.00000, 0.00000\n",
      "H 0.00000, 0.00000, 0.74000\n",
      "INFO:root:Charge: 0\n",
      "INFO:root:Multiplicity: 1\n",
      "INFO:root:Unit: Angstrom\n",
      "INFO:root:\n",
      "#######################################\n",
      "SCF Calculation (Classical)\n",
      "#######################################\n",
      "INFO:root:Basis: sto-3g\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "converged SCF energy = -1.11675930739643\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:root:SCF energy: -1.11676.\n"
     ]
    }
   ],
   "source": [
    "# Build a quantum circuit using HardwareEfficient ansatz.\n",
    "mol.build()\n",
    "n_qubits = mol.num_qubits\n",
    "depth = 2\n",
    "cir = pq_qchem.HardwareEfficient(n_qubits, depth)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, we can call `GroundStateSolver` and use PaddlePaddle's optimizer to update parameters in the ansatz."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:root:\n",
      "#######################################\n",
      "VQE (Ground State)\n",
      "#######################################\n",
      "INFO:root:Number of qubits: 4\n",
      "INFO:root:Ansatz: HardwareEfficient\n",
      "INFO:root:Optimizer: Adam\n",
      "INFO:root:\tlearning_rate: 0.5\n",
      "INFO:root:\n",
      "Optimization:\n",
      "INFO:root:\tItr 0, loss=-0.26383.\n",
      "INFO:root:\tItr 10, loss=-1.02679.\n",
      "INFO:root:\tItr 20, loss=-1.08981.\n",
      "INFO:root:\tItr 30, loss=-1.12582.\n",
      "INFO:root:\tItr 40, loss=-1.13435.\n",
      "INFO:root:\tItr 50, loss=-1.13531.\n",
      "INFO:root:\tItr 60, loss=-1.13634.\n",
      "INFO:root:\tItr 70, loss=-1.13713.\n",
      "INFO:root:Optimization converged after 73 iterations.\n",
      "INFO:root:The final loss = -1.13703.\n"
     ]
    }
   ],
   "source": [
    "# We choose `Adam` optimizer in PaddlePaddle\n",
    "from paddle.optimizer import Adam\n",
    "\n",
    "solver = pq_qchem.GroundStateSolver(Adam, num_iterations=100, tol=1e-5, save_every=10)\n",
    "e, psi = solver.solve(mol, cir, learning_rate=0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "## References\n",
    "\n",
    "[1] Kandala, Abhinav, et al. \"Hardware-efficient variational quantum eigensolver for small molecules and quantum magnets.\" [Nature 549.7671 (2017): 242-246.](https://www.nature.com/articles/nature23879)\n",
    "\n",
    "[2] Arute, Frank, et al. \"Hartree-Fock on a superconducting qubit quantum computer.\" [Science 369.6507 (2020): 1084-1089.](https://www.science.org/doi/10.1126/science.abb9811)\n",
    "\n",
    "[3] Abhinav, Aspuru-Guzik, et al. \"A Quantum Computing View on Unitary Coupled Cluster Theory\" (https://arxiv.org/abs/2109.15176)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "modellib",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.15"
  },
  "vscode": {
   "interpreter": {
    "hash": "8f24120f890011f53feb4ed62c47961d8565ec1de8b7cb23548c15bd6da8f2d2"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
